#ifndef TCP_H_
#define TCP_H_

class TCPState;
class TCPConnection;

class TCPState
{
public:
	virtual ~TCPState() {};

public:
	virtual void open(TCPConnection*) = 0;
	virtual void close(TCPConnection*) = 0;
	virtual void work(TCPConnection*) = 0;

	virtual void changeState(TCPConnection*, TCPState*);
};

class TCPOpenedState : public TCPState
{
private:
	TCPOpenedState() {}
	virtual ~TCPOpenedState() {}

public:
	static TCPState* instance();

public:
	void open(TCPConnection*);
	void close(TCPConnection*);
	void work(TCPConnection*);

private:
	static TCPState* m_state;
};

class TCPClosedState : public TCPState
{
private:
	TCPClosedState() {}
	virtual ~TCPClosedState() {}

public:
	static TCPState* instance();

public:
	void open(TCPConnection*);
	void close(TCPConnection*);
	void work(TCPConnection*);

private:
	static TCPState* m_state;
};

class TCPOpenedStateCleaner
{
public:
	~TCPOpenedStateCleaner()
	{
		if (TCPOpenedState::instance())
		{
			delete TCPOpenedState::instance();
		}
	}
};

class TCPClosedStateCleaner
{
public:
	~TCPClosedStateCleaner()
	{
		if (TCPClosedState::instance())
		{
			delete TCPClosedState::instance();
		}
	}
};

class TCPConnection
{
public:
	TCPConnection();

public:
	void open();
	void close();
	void work();

protected:
	friend class TCPState;
	void changeState(TCPState*);

private:
	TCPState* m_TCPState;
};

#endif // TCP_H_
